home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / term / extras / source / term-source.lha / termRaster.c < prev    next >
C/C++ Source or Header  |  1995-02-07  |  8KB  |  459 lines

  1. /*
  2. **    termRaster.c
  3. **
  4. **    Screen character (raster) buffering routines
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* DeleteRaster():
  13.      *
  14.      *    Free the contents of the character raster.
  15.      */
  16.  
  17. VOID
  18. DeleteRaster()
  19. {
  20.     if(RasterSemaphore)
  21.     {
  22.         FreeVecPooled(RasterSemaphore);
  23.  
  24.         RasterSemaphore = NULL;
  25.     }
  26.  
  27.     if(Raster)
  28.     {
  29.         FreeVecPooled(Raster);
  30.  
  31.         Raster = NULL;
  32.     }
  33.  
  34.     if(RasterAttr)
  35.     {
  36.         FreeVecPooled(RasterAttr);
  37.  
  38.         RasterAttr = NULL;
  39.     }
  40. }
  41.  
  42.     /* CreateRaster():
  43.      *
  44.      *    Create the character raster.
  45.      */
  46.  
  47. BYTE
  48. CreateRaster()
  49. {
  50.         /* Width of the screen * 2 (in characters),
  51.          * extra for double width. The window size
  52.          * may change, the screen size hopefully
  53.          * doesn't.
  54.          */
  55.  
  56.     RasterWidth    = (Window -> WScreen -> Width / TextFontWidth) * 2;
  57.  
  58.         /* Height of the character raster. */
  59.  
  60.     RasterHeight    = Window -> WScreen -> Height / TextFontHeight;
  61.  
  62.         /* Allocate the raster. */
  63.  
  64.     if(Raster = (STRPTR)AllocVecPooled(RasterWidth * RasterHeight,MEMF_ANY | MEMF_CLEAR))
  65.     {
  66.             /* Allocate the raster attributes. */
  67.  
  68.         if(RasterAttr = (STRPTR)AllocVecPooled(RasterHeight,MEMF_ANY | MEMF_CLEAR))
  69.         {
  70.             if(RasterSemaphore = (struct SignalSemaphore *)AllocVecPooled(sizeof(struct SignalSemaphore),MEMF_ANY))
  71.             {
  72.                 InitSemaphore(RasterSemaphore);
  73.  
  74.                 return(TRUE);
  75.             }
  76.         }
  77.     }
  78.  
  79.     DeleteRaster();
  80.  
  81.     return(FALSE);
  82. }
  83.  
  84.     /* RasterEraseScreen(BYTE Mode):
  85.      *
  86.      *    Erase parts of the screen.
  87.      */
  88.  
  89. VOID __regargs
  90. RasterEraseScreen(BYTE Mode)
  91. {
  92.     LONG    First,
  93.         Last;
  94.  
  95.     ObtainSemaphore(RasterSemaphore);
  96.  
  97.     switch(Mode)
  98.     {
  99.         case 1:    First    = 0;
  100.             Last    = CursorY * RasterWidth + CursorX + 1;
  101.  
  102.             memset(RasterAttr,SCALE_NORMAL,CursorY + 1);
  103.  
  104.             break;
  105.  
  106.         case 2:    First    = 0;
  107.             Last    = RasterHeight * RasterWidth - 1;
  108.  
  109.             memset(RasterAttr,SCALE_NORMAL,RasterHeight);
  110.  
  111.             break;
  112.  
  113.         default:First    = CursorY * RasterWidth + CursorX;
  114.             Last    = RasterHeight * RasterWidth - 1;
  115.  
  116.             memset(&RasterAttr[CursorY],SCALE_NORMAL,RasterHeight - CursorY);
  117.  
  118.             break;
  119.     }
  120.  
  121.     RethinkRasterLimit();
  122.  
  123.     if(Last > First)
  124.         memset(&Raster[First],' ',Last - First);
  125.  
  126.     ConFontScaleUpdate();
  127.  
  128.     ReleaseSemaphore(RasterSemaphore);
  129. }
  130.  
  131.     /* RasterEraseLine(BYTE Mode):
  132.      *
  133.      *    Erase parts of the current cursor line.
  134.      */
  135.  
  136. VOID __regargs
  137. RasterEraseLine(BYTE Mode)
  138. {
  139.     LONG    First,
  140.         Last;
  141.  
  142.     ObtainSemaphore(RasterSemaphore);
  143.  
  144.     switch(Mode)
  145.     {
  146.             /* From beginning to current cursor position. */
  147.  
  148.         case 1:    First    = CursorY * RasterWidth;
  149.             Last    = First + CursorX + 1;
  150.  
  151.             break;
  152.  
  153.             /* Entire line. */
  154.  
  155.         case 2:    First    = CursorY * RasterWidth;
  156.             Last    = First + RasterWidth - 1;
  157.  
  158.             break;
  159.  
  160.             /* From current cursor position towards end. */
  161.  
  162.         default:First    = CursorY * RasterWidth + CursorX;
  163.             Last    = (CursorY + 1) * RasterWidth - 1;
  164.  
  165.             break;
  166.     }
  167.  
  168.     if(Last > First)
  169.         memset(&Raster[First],' ',Last - First);
  170.  
  171.     ReleaseSemaphore(RasterSemaphore);
  172. }
  173.  
  174.     /* RasterEraseCharacters(WORD Chars):
  175.      *
  176.      *    Erase a number of characters in the current cursor
  177.      *    line.
  178.      */
  179.  
  180. VOID __regargs
  181. RasterEraseCharacters(WORD Chars)
  182. {
  183.     if(CursorX < RasterWidth - 1)
  184.     {
  185.         LONG     First,
  186.              Diff;
  187.         UBYTE    *To,
  188.             *From;
  189.  
  190.         ObtainSemaphore(RasterSemaphore);
  191.  
  192.         First    = CursorY * RasterWidth + CursorX;
  193.         To    = &Raster[First];
  194.  
  195.         if(CursorX + Chars >= RasterWidth)
  196.         {
  197.             Diff = RasterWidth - 1 - CursorX;
  198.  
  199.             while(Diff-- > 0)
  200.                 *To++ = ' ';
  201.         }
  202.         else
  203.         {
  204.             From    = &Raster[First + Chars];
  205.             Diff    = RasterWidth - (CursorX + 1 + Chars);
  206.  
  207.             while(Diff--)
  208.             {
  209.                 *To++ = *From;
  210.  
  211.                 *From++ = ' ';
  212.             }
  213.         }
  214.  
  215.         ReleaseSemaphore(RasterSemaphore);
  216.     }
  217. }
  218.  
  219.     /* RasterClearLine(WORD Lines):
  220.      *
  221.      *    Clear and remove a number of lines.
  222.      */
  223.  
  224. VOID __regargs
  225. RasterClearLine(WORD Lines,WORD Top)
  226. {
  227.     if(Lines)
  228.     {
  229.         LONG RegionBottom;
  230.  
  231.         ObtainSemaphore(RasterSemaphore);
  232.  
  233.         if(RegionSet)
  234.             RegionBottom = Bottom;
  235.         else
  236.             RegionBottom = LastLine + 1;
  237.  
  238.         if(Top + Lines >= RegionBottom)
  239.             RasterEraseScreen(0);
  240.         else
  241.         {
  242.             LONG     Max;
  243.             UBYTE    *From,
  244.                 *To;
  245.  
  246.             Max    = (RegionBottom - (Top + Lines)) * RasterWidth;
  247.  
  248.             From    = &Raster[(Top + Lines) * RasterWidth];
  249.             To    = &Raster[ Top          * RasterWidth];
  250.  
  251.             while(Max--)
  252.             {
  253.                 *To++ = *From;
  254.  
  255.                 *From++ = ' ';
  256.             }
  257.  
  258.             memset(&RasterAttr[RegionBottom - Lines],SCALE_NORMAL,Lines);
  259.         }
  260.  
  261.         RethinkRasterLimit();
  262.  
  263.         ConFontScaleUpdate();
  264.  
  265.         ReleaseSemaphore(RasterSemaphore);
  266.     }
  267. }
  268.  
  269.     /* RasterInsertLine(WORD Lines):
  270.      *
  271.      *    Insert a number of lines at the current cursor line.
  272.      */
  273.  
  274. VOID __regargs
  275. RasterInsertLine(WORD Lines,WORD Top)
  276. {
  277.     if(Lines)
  278.     {
  279.         LONG RegionBottom;
  280.  
  281.         if(RegionSet)
  282.             RegionBottom = Bottom;
  283.         else
  284.             RegionBottom = LastLine + 1;
  285.  
  286.         if(Top + Lines > RegionBottom)
  287.             RasterEraseScreen(0);
  288.         else
  289.         {
  290.             LONG     From,To,
  291.                  Max;
  292.             UBYTE    *FromPtr,
  293.                 *ToPtr;
  294.  
  295.             ObtainSemaphore(RasterSemaphore);
  296.  
  297.             Max    = (RegionBottom - Lines - Top) * RasterWidth;
  298.  
  299.             From    = (RegionBottom - Lines) * RasterWidth - 1;
  300.             To    =  RegionBottom          * RasterWidth - 1;
  301.  
  302.             FromPtr    = &Raster[From];
  303.             ToPtr    = &Raster[To];
  304.  
  305.             while(Max--)
  306.                 *ToPtr-- = *FromPtr--;
  307.  
  308.             memset(&Raster[Top * RasterWidth],' ',Lines * RasterWidth);
  309.  
  310.             ReleaseSemaphore(RasterSemaphore);
  311.         }
  312.     }
  313. }
  314.  
  315.     /* RasterScrollRegion(WORD Direction,WORD RasterTop,WORD RasterBottom,WORD RasterLines):
  316.      *
  317.      *    Scroll the contents of the character raster up/down.
  318.      */
  319.  
  320. VOID __regargs
  321. RasterScrollRegion(WORD Direction,WORD RasterTop,WORD RasterBottom,WORD RasterLines)
  322. {
  323.     WORD Dir = ABS(Direction);
  324.  
  325.     ObtainSemaphore(RasterSemaphore);
  326.  
  327.     if(Dir >= RasterLines)
  328.     {
  329.             /* All that is needed is to delete the lines. */
  330.  
  331.         memset(&Raster[RasterTop * RasterWidth],' ',RasterLines * RasterWidth);
  332.     }
  333.     else
  334.     {
  335.         LONG     First,
  336.              Last,
  337.              Max,
  338.              i;
  339.         UBYTE    *From,
  340.             *To;
  341.  
  342.         Max = (RasterLines - Dir) * RasterWidth;
  343.  
  344.         if(Direction < 0)
  345.         {
  346.             First    = (RasterTop + RasterLines - Dir) * RasterWidth - 1;
  347.             Last    = (RasterTop + RasterLines    ) * RasterWidth - 1;
  348.  
  349.             From    = &Raster[First];
  350.             To    = &Raster[Last];
  351.  
  352.             while(Max--)
  353.                 *To-- = *From--;
  354.  
  355.             for(i = RasterBottom ; i >= (RasterTop + Dir) ; i--)
  356.                 RasterAttr[i] = RasterAttr[i - Dir];
  357.  
  358.             memset(&Raster[RasterTop * RasterWidth],' ',RasterWidth * Dir);
  359.  
  360.             memset(&RasterAttr[RasterTop],SCALE_NORMAL,Dir);
  361.         }
  362.         else
  363.         {
  364.             First    = RasterTop * RasterWidth + RasterWidth * Dir;
  365.             Last    = RasterTop * RasterWidth;
  366.  
  367.             From    = &Raster[First];
  368.             To    = &Raster[Last];
  369.  
  370.             while(Max--)
  371.                 *To++ = *From++;
  372.  
  373.             memset(&Raster[(RasterBottom - Dir) * RasterWidth],' ',RasterWidth * Dir);
  374.  
  375.             for(i = RasterTop ; i <= (RasterBottom - Dir) ; i++)
  376.                 RasterAttr[i] = RasterAttr[i + Dir];
  377.  
  378.             memset(&RasterAttr[RasterBottom - Dir],SCALE_NORMAL,Dir);
  379.         }
  380.     }
  381.  
  382.     RethinkRasterLimit();
  383.  
  384.     ConFontScaleUpdate();
  385.  
  386.     ReleaseSemaphore(RasterSemaphore);
  387. }
  388.  
  389.     /* RasterShiftChar(WORD Size):
  390.      *
  391.      *    Shift the characters following the current cursor
  392.      *    position Size characters to the right.
  393.      */
  394.  
  395. VOID __regargs
  396. RasterShiftChar(WORD Size)
  397. {
  398.     LONG     i,
  399.          First;
  400.     UBYTE    *From,
  401.         *To;
  402.  
  403.     ObtainSemaphore(RasterSemaphore);
  404.  
  405.     if(CursorX + Size >= RasterWidth - 1)
  406.     {
  407.         i    = RasterWidth - 1 - CursorX;
  408.         To    = &Raster[CursorY * RasterWidth + CursorX];
  409.  
  410.         while(i-- > 0)
  411.             *To++ = ' ';
  412.     }
  413.     else
  414.     {
  415.         First    = (CursorY + 1) * RasterWidth - 1;
  416.         To    = &Raster[First];
  417.  
  418.         From    = &Raster[First - Size];
  419.         i    = RasterWidth - Size;
  420.  
  421.         while(i-- > CursorX)
  422.             *To-- = *From--;
  423.  
  424.         To    = &Raster[CursorY * RasterWidth + CursorX];
  425.  
  426.         while(Size--)
  427.             *To++ = ' ';
  428.     }
  429.  
  430.     ReleaseSemaphore(RasterSemaphore);
  431. }
  432.  
  433.     /* RasterPutString(STRPTR String,WORD Length):
  434.      *
  435.      *    Put a string into the character raster.
  436.      */
  437.  
  438. VOID __regargs
  439. RasterPutString(STRPTR String,WORD Length)
  440. {
  441.     ObtainSemaphore(RasterSemaphore);
  442.  
  443.     if(Length == 1)
  444.     {
  445.         if(CursorX + 1 < RasterWidth)
  446.             Raster[CursorY * RasterWidth + CursorX] = String[0];
  447.     }
  448.     else
  449.     {
  450.         if(CursorX + Length >= RasterWidth)
  451.             Length = RasterWidth - 1 - CursorX;
  452.  
  453.         if(Length > 0)
  454.             memcpy(&Raster[CursorY * RasterWidth + CursorX],String,Length);
  455.     }
  456.  
  457.     ReleaseSemaphore(RasterSemaphore);
  458. }
  459.